//
//  DetailView.swift
//  Speek
//
//  Created by MikeHo on 2023/6/19.
//

import SwiftUI
import CoreData

struct DetailView: View {
    //选择分类变量
    @Binding var isShowTypeSelect : Bool
    @State private var isSelected = false
    @State private var selectType = ""
    
    //选择日期变量
    //@State private var monthlyBillShowing : [MonthlyBill]
    @State private var isShowDateSelect = false
    //@State private var yearArray : [String] = []
    //@State private var monthArray : [String] = []
    //@State private var selectBillYear = ""
    //@State private var selectBillMonth = ""
    //@State private var scrollToBillID: UUID? // 添加一个变量来保存要滚动到的账单ID

    //访问coreData中BillDetail类型数据
    @FetchRequest(entity:BillDetail.entity(),sortDescriptors: [NSSortDescriptor(keyPath: \BillDetail.date , ascending: false)],animation: .easeInOut(duration: 0.3)) private var bills:FetchedResults<BillDetail>
    
    let calendar = Calendar.current
    
    @Environment(\.managedObjectContext) private var context
    
    var body: some View {
        VStack{
            if bills.isEmpty{
                VStack(spacing:10){
                    Text("尚无交易信息")
                    Text("快去添加账单吧")
                }
                .preferredColorScheme(.dark)
                .frame(alignment: .center)
                .font(.title)
            }else{
                //ScrollViewReader { scrollViewProxy in
                    ScrollView{
                        LazyVStack(spacing: 5){
                            let monthlyBillShowing = selectType.isEmpty ? getMonthlyBills() : getMonthlyBills(selectedType: selectType)
                            ForEach(monthlyBillShowing,id:\.id){monthlyBill in
                                ScrollCardView(sameDateBill: monthlyBill, isShowDateSelect: $isShowDateSelect)
                            }
                            .padding(.bottom,10)
                        }
                    }
            }
        }
        //选择账单分类界面
        .sheet(isPresented: $isShowTypeSelect){
            BillTypeSelect(isSelected: $isSelected, selectType: $selectType)
                .presentationDetents([.large])
                .presentationDragIndicator(.hidden)
                .interactiveDismissDisabled()
                .navigationBarTitle("",displayMode: .inline)
        }
    }
   
    private func dateFormatter(date:Date)->String{
        let Formatter = DateFormatter()
        Formatter.dateFormat = "yyyy年MM月"
        let formattedDate = Formatter.string(from: date)
        return formattedDate
    }
    
  
    
    //获取数据库中最小的日期
    private func getMinDate() -> Date? {
        let fetchRequest: NSFetchRequest<NSDictionary> = NSFetchRequest(entityName: "BillDetail")
        
        let expressionDescription = NSExpressionDescription()
        expressionDescription.name = "minDate"
        expressionDescription.expression = NSExpression(forFunction: "min:", arguments: [NSExpression(forKeyPath: "date")])
        expressionDescription.expressionResultType = .dateAttributeType
        
        fetchRequest.resultType = .dictionaryResultType
        fetchRequest.propertiesToFetch = [expressionDescription]
        
        do {
            let results = try context.fetch(fetchRequest)
            if let result = results.first, let minDate = result["minDate"] as? Date {
                return minDate
            }
        } catch {
            print("Error fetching minimum date: \(error)")
        }
        
        return nil
    }
    
 
    //获取一个存有相同年份/月份的BillDetail数组的数组
    private func getMonthlyBills(selectedType: String? = nil) -> [MonthlyBill] {
        guard let minDate = getMinDate() else {
            return []
        }
        
        let calendar = Calendar.current
        var currentDate = minDate
        let minDay = calendar.component(.day, from: minDate)
        let currentDay = calendar.component(.day, from: Date())

        if minDay > currentDay {
            // 最小日期的日大于当前日期的日，将最小日期设置为当前日期的前一天
            currentDate = calendar.date(bySetting: .day, value: currentDay, of: currentDate)!
        }
        
        var monthlyBills: [MonthlyBill] = []
        
        while currentDate < Date(){
            
            let currentYear = calendar.component(.year, from: currentDate)
            let currentMonth = calendar.component(.month, from: currentDate)
            
            let billDetails = getBillDetails(forYear: currentYear, month: currentMonth, withType: selectedType)
            
            if(billDetails.isEmpty == false){
                let monthString = String(currentMonth)
                let yearString = String(currentYear)
                let monthlyOutput = getTotalAmount(forYear: currentYear, month: currentMonth, tag: false, selectedType: selectedType)
                let monthlyIncome = getTotalAmount(forYear: currentYear, month: currentMonth, tag: true, selectedType: selectedType)
                
                let monthlyBill = MonthlyBill(month: monthString, year: yearString, billsArray: billDetails,totalOutput: monthlyOutput,totalIncome: monthlyIncome)
                monthlyBills.append(monthlyBill)
                
                currentDate = calendar.date(byAdding: .month, value: 1, to: currentDate)!
            }else{
                currentDate = calendar.date(byAdding: .month, value: 1, to: currentDate)!
            }
        }
        
        // 按时间从大到小排序数组
        monthlyBills.sort { (bill1, bill2) -> Bool in
            let date1 = calendar.date(from: DateComponents(year: Int(bill1.year), month: Int(bill1.month)))
            let date2 = calendar.date(from: DateComponents(year: Int(bill2.year), month: Int(bill2.month)))
            return date1?.compare(date2!) == .orderedDescending
        }
        return monthlyBills
    }

}

//获取某年某月支出/收入的总金额
 func getTotalAmount(forYear year: Int, month: Int, tag: Bool, selectedType: String? = nil) -> Double {
    let billDetails = getBillDetails(forYear: year, month: month,withType: selectedType)
    
    let filteredBillDetails = billDetails.filter { $0.tag == tag }
    let totalAmount = filteredBillDetails.reduce(0) { $0 + $1.cost }
    
    return totalAmount
}


//获取具体年份和月份的账单数组
 func getBillDetails(forYear year: Int, month: Int,withType type: String? = nil) -> [BillDetail] {
     
    let context = PersistenceController.shared.container.viewContext

    let calendar = Calendar.current
    let dateComponents = DateComponents(year: year, month: month)
    let startDate = calendar.date(from: dateComponents)!
    let endDate = calendar.date(byAdding: .month, value: 1, to: startDate)!
    
    var predicate: NSPredicate?
    if let selectedType = type {
             predicate = NSPredicate(format: "date >= %@ AND date <= %@ AND type == %@", startDate as NSDate, endDate as NSDate, selectedType)
    } else {
        predicate = NSPredicate(format: "date >= %@ AND date <= %@", startDate as NSDate, endDate as NSDate)
    }
    
    let sortDescriptor = NSSortDescriptor(key: "date", ascending: false)
    
    let fetchRequest: NSFetchRequest<BillDetail> = BillDetail.fetchRequest()
    fetchRequest.predicate = predicate
    fetchRequest.sortDescriptors = [sortDescriptor]
    
    do {
        let results = try context.fetch(fetchRequest)
        return results
    } catch {
        print("Error fetching bills: \(error)")
        return []
    }
}

struct DetailView_Previews: PreviewProvider {
    static var previews: some View {
        SecondView()
    }
}
